import unittest

from Autotests.BaseTest import BaseManservSOAPTestCase, PartnerAndAccountAutoCreation


@PartnerAndAccountAutoCreation
class NotificationRulesTemplatesTransports(BaseManservSOAPTestCase):
    def __init__(self, *args, **kwargs):
        BaseManservSOAPTestCase.__init__(self, *args, **kwargs)

    def setUp(self, *args, **kwargs):
        BaseManservSOAPTestCase.setUp(self, *args, **kwargs)
        self._templateId = 100
        self._baseTransport = {
            'id': 100,
            'partnerId': self.getPartnerForCaseInfo().id,
            'type': {
                'value': 'Smtp',
            },
            'parameters': 'testParameters',
        }
        self._baseRule = {
            'id': 100,
            'name': 'Test rule',
            'entity': {'value': 'Account'},
            'partnerId': self.getPartnerForCaseInfo().id,
            'expression': '1>0',
            'predicate': {'value': 'True'},
            'schedule': '0 8 * *',
            'transportType': {'value': 'Smtp'},
            'templateId': str(self._templateId),
            'recipients': '<%email%>',
            'enabled': True,
            'revision': 1,
        }
        self._baseTemplate = {
            'id': 100,
            'templateId': self._templateId,
            'name': 'Test template name',
            'partnerId': self.getPartnerForCaseInfo().id,
            'body': 'Test template body',
        }
        self._createdTemplateId = None
        self._createdTransportId = None
        self._createdRuleId = None

    def test_AddNotificationRule(self):
        count = self._getRulesCount()
        result = self._createRule()
        self.assertTrue(result.isnumeric())
        countAfter = self._getRulesCount()
        self.assertEqual(count + 1, countAfter)

        self._deleteRule()

    def test_AddNotificationTemplate(self):
        count = self._getTemplatesCount()
        result = self._createTemplate()
        self.assertTrue(result.isnumeric())
        countAfter = self._getTemplatesCount()
        self.assertEqual(count + 1, countAfter)

        self._deleteTemplate()

    def test_AddNotificationTransport(self):
        count = self._getTransportsCount()
        result = self._createTransport()
        self.assertTrue(result.isnumeric())
        countAfter = self._getTransportsCount()
        self.assertEqual(count + 1, countAfter)

        self._deleteTransport()

    def test_EnableNotificationRule(self):
        ruleId = self._createRule()
        count1 = self._getActiveRulesCount()
        result = self.manserv.EnableNotificationRule(id = ruleId,
                                                     partnerId = self.getPartnerForCaseInfo().id,
                                                     enable = False)
        self.assertIsNone(result)
        count2 = self._getActiveRulesCount()
        self.assertEqual(count1 - 1, count2)
        self.manserv.EnableNotificationRule(id = ruleId,
                                                     partnerId = self.getPartnerForCaseInfo().id,
                                                     enable = True)
        count3 = self._getActiveRulesCount()
        self.assertEqual(count2 + 1, count3)

        self._deleteRule()

    def test_EnumerateActiveNotificationRules(self):
        self._createRule()
        result = self.manserv.EnumerateActiveNotificationRules()
        self.assertEqual(result.notificationRules[-1].enabled, self._baseRule['enabled'])
        self.assertEqual(result.notificationRules[-1].entity, self._baseRule['entity']['value'])
        self.assertEqual(result.notificationRules[-1].expression, self._baseRule['expression'])
        self.assertEqual(result.notificationRules[-1].id, int(self._createdRuleId))
        self.assertEqual(result.notificationRules[-1].name, self._baseRule['name'])
        self.assertEqual(result.notificationRules[-1].partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(result.notificationRules[-1].predicate, self._baseRule['predicate']['value'])
        self.assertEqual(result.notificationRules[-1].recipients, self._baseRule['recipients'])
        self.assertEqual(result.notificationRules[-1].schedule, self._baseRule['schedule'])
        self.assertEqual(result.notificationRules[-1].templateId, self._baseRule['templateId'])
        self.assertEqual(result.notificationRules[-1].transportType, self._baseRule['transportType']['value'])

        self._deleteRule()

    def test_EnumerateAllNotificationTransports(self):
        transportId = self._createTransport()
        result = self.manserv.EnumerateAllNotificationTransports()
        self.assertEqual(result.notificationTransports[-1].parameters, self._baseTransport['parameters'])
        self.assertEqual(str(result.notificationTransports[-1].id), transportId)
        self.assertEqual(result.notificationTransports[-1].partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(result.notificationTransports[-1].type, self._baseTransport['type']['value'])

        self._deleteTransport()

    def test_EnumerateNotificationRules(self):
        self._createRule()
        result = self.manserv.EnumerateNotificationRules(partnerId = self.getPartnerForCaseInfo().id)
        self.assertEqual(result.notificationRules[0].enabled, self._baseRule['enabled'])
        self.assertEqual(result.notificationRules[0].entity, self._baseRule['entity']['value'])
        self.assertEqual(result.notificationRules[0].expression, self._baseRule['expression'])
        self.assertEqual(result.notificationRules[0].id, int(self._createdRuleId))
        self.assertEqual(result.notificationRules[0].name, self._baseRule['name'])
        self.assertEqual(result.notificationRules[0].partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(result.notificationRules[0].predicate, self._baseRule['predicate']['value'])
        self.assertEqual(result.notificationRules[0].recipients, self._baseRule['recipients'])
        self.assertEqual(result.notificationRules[0].schedule, self._baseRule['schedule'])
        self.assertEqual(result.notificationRules[0].templateId, self._baseRule['templateId'])
        self.assertEqual(result.notificationRules[0].transportType, self._baseRule['transportType']['value'])

        self._deleteRule()

    def test_EnumerateNotificationTransports(self):
        result = self.manserv.EnumerateNotificationTransports(partnerId = self.getPartnerForCaseInfo().id)
        self.assertEqual(result, '')
        transportId = self._createTransport()
        resultAfter = self.manserv.EnumerateNotificationTransports(partnerId = self.getPartnerForCaseInfo().id)
        self.assertEqual(str(resultAfter.notificationTransports[0].id), transportId)
        self.assertEqual(resultAfter.notificationTransports[0].parameters, self._baseTransport['parameters'])
        self.assertEqual(resultAfter.notificationTransports[0].partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(resultAfter.notificationTransports[0].type, self._baseTransport['type']['value'])

        self._deleteTransport()

    def test_EnumerateTemplates(self):
        result = self.manserv.EnumerateTemplates(partnerId = self.getPartnerForCaseInfo().id, partnerOnly = True)
        self.assertEqual(result, '')
        allTemplatesCount = self._getTemplatesCount(isPartnerOnly=False)

        templateId = self._createTemplate()

        resultAfter = self.manserv.EnumerateTemplates(partnerId = self.getPartnerForCaseInfo().id, partnerOnly = True)

        self.assertEqual(str(resultAfter.notificationTemplates[0]['id']), templateId)
        self.assertEqual(resultAfter.notificationTemplates[0]['templateId'], self._baseTemplate['templateId'])
        self.assertEqual(resultAfter.notificationTemplates[0]['name'], self._baseTemplate['name'])
        self.assertEqual(resultAfter.notificationTemplates[0]['partnerId'], self.getPartnerForCaseInfo().id)

        allTemplatesCountAfter = self._getTemplatesCount(isPartnerOnly=False)
        self.assertEqual(allTemplatesCount + 1, allTemplatesCountAfter)
        allTemplates = self.manserv.EnumerateTemplates(partnerId = self.getPartnerForCaseInfo().id, partnerOnly = False)
        self.assertEqual(str(allTemplates.notificationTemplates[0]['id']), templateId)
        self.assertEqual(allTemplates.notificationTemplates[0]['templateId'], self._baseTemplate['templateId'])
        self.assertEqual(allTemplates.notificationTemplates[0]['name'], self._baseTemplate['name'])
        self.assertEqual(allTemplates.notificationTemplates[0]['partnerId'], self.getPartnerForCaseInfo().id)

        self._deleteTemplate()

    def test_GetNotificationRule(self):
        ruleId = self._createRule()

        result = self.manserv.GetNotificationRule(id = ruleId)

        self.assertEqual(result.enabled, self._baseRule['enabled'])
        self.assertEqual(result.entity, self._baseRule['entity']['value'])
        self.assertEqual(result.expression, self._baseRule['expression'])
        self.assertEqual(result.id, int(ruleId))
        self.assertEqual(result.name, self._baseRule['name'])
        self.assertEqual(result.partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(result.predicate, self._baseRule['predicate']['value'])
        self.assertEqual(result.recipients, self._baseRule['recipients'])
        self.assertEqual(result.schedule, self._baseRule['schedule'])
        self.assertEqual(result.templateId, self._baseRule['templateId'])
        self.assertEqual(result.transportType, self._baseRule['transportType']['value'])

        self._deleteRule()

    def test_GetNotificationTemplate(self):
        templateId = self._createTemplate()
        result = self.manserv.GetNotificationTemplate(id = templateId)
        self.assertEqual(str(result.id), templateId)
        self.assertEqual(result.partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(result.templateId, self._baseTemplate['templateId'])
        self.assertEqual(result.name, self._baseTemplate['name'])

        self._deleteTemplate()

    def test_GetNotificationTransport(self):
        transportId = self._createTransport()
        result = self.manserv.GetNotificationTransport(id = transportId)
        self.assertEqual(str(result.id), transportId)
        self.assertEqual(result.parameters, self._baseTransport['parameters'])
        self.assertEqual(result.partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(result.type, self._baseTransport['type']['value'])

        self._deleteTransport()

    def test_GetPartnerNotificationTemplate(self):
        templateId = self._createTemplate()
        partnerId = self.getPartnerForCaseInfo().id

        with self.assertRaises(Exception) as exc:
            self.manserv.GetPartnerNotificationTemplate(templateId = templateId, partnerId = partnerId)
        self.assertEqual(exc.exception.message, (502, u'Bad Gateway'))

        self._deleteTemplate()

    def test_GetPartnersRuleAppliedTo(self):
        ruleId = self._createRule()
        with self.assertRaises(Exception) as exc:
            self.manserv.GetPartnersRuleAppliedTo(ruleId = ruleId)
        self.assertEqual(exc.exception.message, (502, u'Bad Gateway'))

        self._deleteRule()

    def test_ModifyNotificationRule(self):
        ruleId = self._createRule()

        template = self.manserv.GetNotificationTemplate(id = self._createdTemplateId)

        modifiedRule = self._baseRule.copy()
        modifiedRule['id'] = ruleId
        modifiedRule['name'] = 'New Rule'
        modifiedRule['entity'] = {'value': 'Partner'}
        modifiedRule['expression'] = '1<0'
        modifiedRule['predicate'] = {'value': 'False'}
        modifiedRule['schedule'] = '0 10 * *'
        modifiedRule['transportType'] = {'value': 'AmazonSes'}
        modifiedRule['templateId'] = str(template.templateId)
        modifiedRule['recipients'] = 'mail@mail.ru'
        modifiedRule['enabled'] = False
        modifiedRule['revision'] = 2

        result = self.manserv.ModifyNotificationRule(**modifiedRule)
        self.assertIsNone(result)

        rule = self.manserv.GetNotificationRule(id = ruleId)
        self.assertEqual(rule.name, modifiedRule['name'])
        self.assertEqual(rule.entity, modifiedRule['entity']['value'])
        self.assertEqual(rule.expression, modifiedRule['expression'])
        self.assertEqual(rule.predicate, modifiedRule['predicate']['value'])
        self.assertEqual(rule.schedule, modifiedRule['schedule'])
        self.assertEqual(rule.transportType, modifiedRule['transportType']['value'])
        self.assertEqual(rule.templateId, modifiedRule['templateId'])
        self.assertEqual(rule.recipients, modifiedRule['recipients'])
        self.assertEqual(rule.enabled, self._baseRule['enabled']) # Not changed

        self._deleteRule()

    def test_ModifyNotificationTemplate(self):
        templateId = self._createTemplate()

        templateBody = self.manserv.GetNotificationTemplate(id = templateId).body

        modifiedTemplate = self._baseTemplate.copy()
        modifiedTemplate['id'] = int(templateId)
        modifiedTemplate['name'] = 'A new template name'
        modifiedTemplate['body'] = 'A new template body'
        modifiedTemplate['templateId'] = 200

        result = self.manserv.ModifyNotificationTemplate(**modifiedTemplate)
        self.assertIsNone(result)

        resultTemplate = self.manserv.GetNotificationTemplate(id = templateId)

        self.assertEqual(str(resultTemplate.id), templateId)
        self.assertEqual(resultTemplate.partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(resultTemplate.templateId, self._templateId)
        self.assertEqual(resultTemplate.name, modifiedTemplate['name'])
        self.assertNotEqual(resultTemplate.body, templateBody)

        self._deleteTemplate()

    def test_ModifyNotificationTransport(self):
        newParameters = 'New parameters'
        newType = {'value': 'AmazonSes'}

        transportId = self._createTransport()
        modifiedTransport = self._baseTransport.copy()
        modifiedTransport['id'] = transportId
        modifiedTransport['parameters'] = newParameters
        modifiedTransport['type'] = newType
        result = self.manserv.ModifyNotificationTransport(**modifiedTransport)
        self.assertIsNone(result)

        resultTransport = self.manserv.GetNotificationTransport(id = transportId)
        self.assertEqual(str(resultTransport.id), transportId)
        self.assertEqual(resultTransport.parameters, newParameters)
        self.assertEqual(resultTransport.partnerId, self.getPartnerForCaseInfo().id)
        self.assertEqual(resultTransport.type, newType['value'])

        self._deleteTransport()

    def test_RemoveNotificationRule(self):
        ruleId = self._createRule()
        count = self._getRulesCount()
        result = self.manserv.RemoveNotificationRule(id = ruleId)
        self.assertIsNone(result)
        countAfter = self._getRulesCount()
        self.assertEqual(count - 1, countAfter)

    def test_RemoveNotificationTemplate(self):
        templateId = self._createTemplate()
        count = self._getTemplatesCount()
        result = self.manserv.RemoveNotificationTemplate(id = templateId)
        self.assertIsNone(result)
        countAfter = self._getTemplatesCount()
        self.assertEqual(count - 1, countAfter)

    def test_RemoveNotificationTransport(self):
        transportId = self._createTransport()
        count = self._getTransportsCount()
        result = self.manserv.RemoveNotificationTransport(id = transportId)
        self.assertIsNone(result)
        countAfter = self._getTransportsCount()
        self.assertEqual(count - 1, countAfter)

#---
    def _getTransportsCount(self):
        return len(self.manserv.EnumerateAllNotificationTransports().notificationTransports)

    def _createTransport(self):
        self._createdTransportId = self.manserv.AddNotificationTransport(**self._baseTransport)
        return self._createdTransportId

    def _deleteTransport(self):
        self.manserv.RemoveNotificationTransport(id = self._createdTransportId)

    def _getTemplatesCount(self, isPartnerOnly = True):
        result = self.manserv.EnumerateTemplates(partnerId = self.getPartnerForCaseInfo().id,
                                                 partnerOnly = isPartnerOnly)
        if result == '':
            return 0
        return len(result.notificationTemplates)

    def _createTemplate(self):
        self._createdTemplateId = self.manserv.AddNotificationTemplate(**self._baseTemplate)
        return self._createdTemplateId

    def _deleteTemplate(self):
        self.manserv.RemoveNotificationTemplate(id = self._createdTemplateId)

    def _getRulesCount(self):
        result = self.manserv.EnumerateNotificationRules(partnerId = self.getPartnerForCaseInfo().id)
        if result == '':
            return 0
        return len(result.notificationRules)

    def _getActiveRulesCount(self):
        return self.sudsSequenceLen(self.manserv.EnumerateActiveNotificationRules(), 'notificationRules')

    def _createRule(self):
        rule = self._baseRule.copy()
        templateId = self._createTemplate()
        template = self.manserv.GetNotificationTemplate(id = templateId)
        rule['templateId'] = str(template.templateId)
        self._createdRuleId = self.manserv.AddNotificationRule(**rule)
        return self._createdRuleId

    def _deleteRule(self):
        self.manserv.RemoveNotificationRule(id = self._createdRuleId)
        self.manserv.RemoveNotificationTemplate(id = self._createdTemplateId)


if __name__ == "__main__":
    unittest.main()